首先要和我的團隊隊友們道歉,因為肥宅我廢到出水,居然在電腦前面睡著忘記發文..
起來的時候已經十二點半,誠心在這邊跟其他三位隊友致歉
這邊是他們三位的鐵人貼文:
Ohmyk8s: https://ithelp.ithome.com.tw/users/20120251/articles
hwchiu: https://ithelp.ithome.com.tw/users/20120317/articles
David Chang: https://ithelp.ithome.com.tw/users/20120327/articles
祝福他們可以順利完賽, 另外我也會繼續PO文, 留言我都有看到噢! 歡迎各位不吝給予指教 :D
只是沒完成新手任務回不了留言...
今天會簡單介紹一下:
NodePort | LoadBalancer | |
---|---|---|
優點 | 設定很方便 | 1.如果所使用的公有雲有支援,使用起來就跟NodePort一樣方便 2.支援HTTP, TCP, UDP, Websockets, gRPC等Protocol |
缺點 | 1.暴露主機位址2.主機上開洞,增加資安管理負擔3.新增主機時還要重新設定 | 1.公有雲的loadbalancer很貴2.每個服務都要開一個Load Balancer, 服務一多會非常難管理 |
聽起來兩種方式在正式環境上營運都有相當的負擔,那有沒有更好的方法呢?
當然有, 且看Ingress。
![](https://i.imgur.com/Qvx7fRR.png =300x)
Ingress 並不是一種Service type, 他是一種介面。 假設今天你有service1, service2, 設置好了兩個ingress rules:
http://service.test.com/service1
http://service.test.com/service2
用戶就可以透過這兩個url訪問到service1和service2。
根據官方文件的說明,ingress需要搭配ingress controller使用, 這個ingress controller就是為後面的Service提供一個統一的入口,ingress controller以Pod的形式提供服務,並隨時監控api server的services, 如果有變化就會自動更新proxy rules。
先來張圖壓壓驚:
Nginx Ingress Controller是K8s目前有在維護,並且預設的Ingress Controller, 所以我在這邊拿它來做示範。
首先把nginx-stable chart加入local repo端並更新helm repo
安裝中...
確認安裝完成(後來我把它安裝到ingress-nginx這個namespace當中,比較清楚)
由上圖可以看到有ingress-controller和default backend這兩個Pods, 其中ingress-controller會在有新的ingress產生時去抓ingress resources, 並且把ingress rule寫進去nginx.conf
可以透過這個指令確認rule是否寫入
kubectl exec -it -n <namespace-of-ingress-controller> <ingress-controller-pod-name> cat /etc/nginx/nginx.conf
default-backend則會在流量進入時負責根據這些rules, 將流量proxy到正確的services。
可以透過打load balancer的方式, 因為現在還沒有設定任何的ingress rule, 所以打根目錄會回404
打 /healthz 則會回200
這邊有個小地方要注意, 如果打load balancer回的是503 error, 可能要下指令看看是不是pod內部有錯:
k logs pod/<ingress-controller-pod-name> -n=ingress-nginx | tail -n 10
或是有可能你的service selector指錯地方, 建議kubectl describe deployment去查。
如果是用AWS ELB可以參考這邊
以nginx為例,創建一個服務(程式碼範例來源:邱牛的部落格)
---
apiVersion: apps/v1 # for versions before 1.9.0 use apps/v1beta2
kind: Deployment
metadata:
name: nginx
spec:
strategy:
type: Recreate
selector:
matchLabels:
app: nginx
replicas: 1
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
volumeMounts:
- name: html-file
mountPath: /usr/share/nginx/html
volumes:
- name: html-file
configMap:
name: nginx-index-v1
---
apiVersion: v1
kind: Service
metadata:
name: nginx
namespace: ingress-nginx
labels:
app: nginx
spec:
ports:
- name: http
port: 80
protocol: TCP
targetPort: 80
selector:
app: nginx
---
kind: ConfigMap
apiVersion: v1
metadata:
name: nginx-index-v1
data:
index.html: Nginx V1
然後再創建ingress指到這個服務
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/rewrite-target: /
name: nginx-demo
namespace: default
spec:
rules:
- http:
paths:
- path: /nginx
backend:
serviceName: nginx
servicePort: 80
最後在瀏覽器上查看結果:
大功告成!
如果有上網查找範例, 很多都會在ingress加上host,例如:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/rewrite-target: /
name: nginx-demo
namespace: default
spec:
rules:
- host: nginx.example.com
http:
paths:
- path: /v1
backend:
serviceName: nginx
servicePort: 80
- path: /v2
backend:
serviceName: nginx-v2
servicePort: 80
但是你真的在瀏覽器上直接打path, 會回傳404,要驗證的話可以用以下方式:
curl -H "Host:nginx.example.com" ${ELB CName}/v1
等到有了domain, 再把他指到ELB。
或是你用NodePort的方式, 就可以直接修改電腦上的 /etc/hosts, 把Cluster nodes的IP後面加上想要測試的domain。
如果你想了解Nginx-controller要如何手工安裝可以參考邱牛的部落格
打完收工。